modernize some dynamic memory usage. (#1334)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Wed, 11 Sep 2024 17:37:25 +0000 (11:37 -0600)
committerGitHub <noreply@github.com>
Wed, 11 Sep 2024 17:37:25 +0000 (11:37 -0600)
* modernize some dynamic memory usage.

* refactor convert_human_[date|time]_format

* convert convert_human_*_format to Qt.

* fix include comment

* use back instead of *rbegin to reference last QChar in QString

defs.h
tpo.cc
tpo.h
util.cc

diff --git a/defs.h b/defs.h
index 2380b89e48e7d3014131d700383facb35b36dbf4..0902154b997bfc16ed4ee9e9c119f4e866e6d294 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -951,8 +951,8 @@ QDateTime dotnet_time_to_qdatetime(long long dotnet);
 long long qdatetime_to_dotnet_time(const QDateTime& dt);
 QString strip_html(const QString& utfstring);
 QString strip_nastyhtml(const QString& in);
-QString convert_human_date_format(const char* human_datef);    /* "MM,YYYY,DD" -> "%m,%Y,%d" */
-QString convert_human_time_format(const char* human_timef);    /* "HH+mm+ss"   -> "%H+%M+%S" */
+QString convert_human_date_format(const QString& human_datef); /* "MM,YYYY,DD" -> "%m,%Y,%d" */
+QString convert_human_time_format(const QString& human_timef); /* "HH+mm+ss"   -> "%H+%M+%S" */
 QString pretty_deg_format(double lat, double lon, char fmt, const char* sep, bool html);    /* decimal ->  dd.dddd or dd mm.mmm or dd mm ss */
 
 QString get_filename(const QString& fname);                    /* extract the filename portion */
diff --git a/tpo.cc b/tpo.cc
index d15b1a5124fa45e2cd539975221caf0254c3baf3..6b8e43c6ab81057470f7bd7fbbeb8aef999c21d8 100644 (file)
--- a/tpo.cc
+++ b/tpo.cc
@@ -83,7 +83,7 @@
 #include <QStringLiteral>       // for qMakeStringPrivate, QStringLiteral
 #include <QtGlobal>             // for qPrintable, Q_UNUSED
 
-#include "defs.h"               // for Waypoint, fatal, route_head, le_read32, waypt_add, track_add_wpt, track_add_head, xfree, xmalloc, doing_rtes, doing_wpts, gb_color, route_add_head, route_add_wpt, unknown_alt, doing_trks
+#include "defs.h"               // for Waypoint, fatal, route_head, le_read32, waypt_add, track_add_wpt, track_add_head, doing_rtes, doing_wpts, gb_color, route_add_head, route_add_wpt, unknown_alt, doing_trks
 #include "gbfile.h"             // for gbfread, gbfgetc, gbfgetint32, gbfreadbuf, gbfseek, gbfgetdbl, gbfgetint16, gbfclose, gbfgetnativecstr, gbfgetuint16, gbfopen_le
 #include "jeeps/gpsmath.h"      // for GPS_Math_Known_Datum_To_WGS84_M
 
@@ -696,8 +696,8 @@ void TpoFormatBase::tpo_process_tracks()
     */
 
     // Read the track bytes into a buffer
-    auto* buf = (unsigned char*) xmalloc(track_byte_count);
-    gbfread(buf, 1, track_byte_count, tpo_file_in);
+    QScopedArrayPointer<unsigned char> buf(new unsigned char[track_byte_count]);
+    gbfread(buf.get(), 1, track_byte_count, tpo_file_in);
 
     // these can be set repeatedly, and retain their value between settings
     //  (even if not used for every trackpoint)
@@ -734,13 +734,13 @@ void TpoFormatBase::tpo_process_tracks()
       // Time to read a new latlong?
       if (!llvalid) {
 
-        lon = le_read32(buf+jj);
+        lon = le_read32(&buf[jj]);
         if constexpr(debug > 3) {
           printf("%02x %02x %02x %02x - raw lon = %d (byte %u)\n", buf[jj], buf[jj+1], buf[jj+2], buf[jj+3], lon,jj);
         }
         jj+=4;
 
-        lat = le_read32(buf+jj);
+        lat = le_read32(&buf[jj]);
         if constexpr(debug > 3) {
           printf("%02x %02x %02x %02x - raw lat = %d (byte %u)\n", buf[jj], buf[jj+1], buf[jj+2], buf[jj+3], lat,jj);
         }
@@ -756,7 +756,7 @@ void TpoFormatBase::tpo_process_tracks()
             && !buf[jj+3]
             && !buf[jj+2]) {
 
-          lonscale = le_read32(buf+jj);
+          lonscale = le_read32(&buf[jj]);
           if constexpr(debug > 3) {
             printf("%02x %02x %02x %02x - raw lon scale = %d (byte %u)\n", buf[jj], buf[jj+1], buf[jj+2], buf[jj+3], lonscale, jj);
           }
@@ -772,7 +772,7 @@ void TpoFormatBase::tpo_process_tracks()
             && !buf[jj+3]
             && !buf[jj+2]) {
 
-          latscale = le_read32(buf+jj);
+          latscale = le_read32(&buf[jj]);
           if constexpr(debug > 3) {
             printf("%02x %02x %02x %02x - raw lat scale = %d (byte %u)\n", buf[jj], buf[jj+1], buf[jj+2], buf[jj+3], latscale, jj);
           }
@@ -797,13 +797,13 @@ void TpoFormatBase::tpo_process_tracks()
 
       // read 8-byte lon+lat, required at start of track or after 0x88 tag
       if (tpmode == GetFullPoint) {
-        lon = le_read32(buf+jj);
+        lon = le_read32(&buf[jj]);
         if constexpr(debug > 3) {
           printf("%02x %02x %02x %02x - raw lon = %d (byte %u)\n", buf[jj], buf[jj+1], buf[jj+2], buf[jj+3], lon,jj);
         }
         jj+=4;
 
-        lat = le_read32(buf+jj);
+        lat = le_read32(&buf[jj]);
         if constexpr(debug > 3) {
           printf("%02x %02x %02x %02x - raw lat = %d (byte %u)\n", buf[jj], buf[jj+1], buf[jj+2], buf[jj+3], lat,jj);
         }
@@ -836,7 +836,7 @@ void TpoFormatBase::tpo_process_tracks()
       // Note that lonscale can begin with 0x88, which should not be confused with GetFullPoint tags.
       if (tpmode == CheckLonScale) {
         if ((jj+3<track_byte_count) && !(buf[jj+3]) && !(buf[jj+2])) {
-          lonscale = le_read32(buf+jj);
+          lonscale = le_read32(&buf[jj]);
           if constexpr(debug > 3) {
             printf("%02x %02x %02x %02x - raw lon scale = %d (byte %u)\n", buf[jj], buf[jj+1], buf[jj+2], buf[jj+3], lonscale, jj);
           }
@@ -855,7 +855,7 @@ void TpoFormatBase::tpo_process_tracks()
       // Note that latscale can begin with 0x88, which should not be confused with GetFullPoint tags.
       if (tpmode == CheckLatScale) {
         if ((jj+3<track_byte_count) && !(buf[jj+3]) && !(buf[jj+2])) {
-          latscale = le_read32(buf+jj);
+          latscale = le_read32(&buf[jj]);
           if constexpr(debug > 3) {
             printf("%02x %02x %02x %02x - raw lat scale = %d (byte %u)\n", buf[jj], buf[jj+1], buf[jj+2], buf[jj+3], latscale, jj);
           }
@@ -1009,14 +1009,13 @@ void TpoFormatBase::tpo_process_tracks()
 #endif
 
     } // end for jj track_byte_count
-    xfree(buf);
   } // end for ii track_count
 } // end of tpo_process_tracks
 
 
 // Waypoint decoder for version 3.x files.
 //
-void TpoFormatBase::tpo_process_waypoints()
+void TpoFormatBase::tpo_process_waypoints(QList<Waypoint>& tpo_wp_index)
 {
   //printf("Processing Waypoints...\n");
 
@@ -1032,8 +1031,8 @@ void TpoFormatBase::tpo_process_waypoints()
 
   // Fetch storage for the waypoint index (needed later for
   // routes)
-  tpo_wp_index = (Waypoint**) xmalloc(sizeof(Waypoint*) * waypoint_count);
-  tpo_index_ptr = 0;
+  tpo_wp_index.clear();
+  tpo_wp_index.reserve(waypoint_count);
 
   if (waypoint_count == 0) {
     return;
@@ -1092,10 +1091,8 @@ void TpoFormatBase::tpo_process_waypoints()
 
     // For routes (later), we need a duplicate of each waypoint
     // indexed by the order we read them in.
-    auto* waypoint_temp2 = new Waypoint(*waypoint_temp);
-
-    // Attach the copy to our index
-    tpo_wp_index[tpo_index_ptr++] = waypoint_temp2;
+    // Attach a copy to our index.
+    tpo_wp_index.append(*waypoint_temp);
 
     // Add the original waypoint to the chain of waypoints
     waypt_add(waypoint_temp);
@@ -1325,11 +1322,11 @@ void TpoFormatBase::tpo_process_text_labels()
 
 // Route decoder for version 3.x files.
 //
-// We depend on tpo_wp_index[] having been malloc'ed and filled-in
-// with pointers to waypoint objects by tpo_process_waypoints()
+// We depend on tpo_wp_index having been filled-in
+// with waypoint objects by the tpo_process_waypoints()
 // function above.
 //
-void TpoFormatBase::tpo_process_routes()
+void TpoFormatBase::tpo_process_routes(const QList<Waypoint>& tpo_wp_index)
 {
   //printf("Processing Routes...\n");
 
@@ -1397,7 +1394,7 @@ void TpoFormatBase::tpo_process_routes()
 //printf("val: %x\t\t", val);
 
       // Duplicate a waypoint from our index of waypoints.
-      auto* waypoint_temp = new Waypoint(*tpo_wp_index[val-1]);
+      auto* waypoint_temp = new Waypoint(tpo_wp_index[val-1]);
 
       // Add the waypoint to the route
       route_add_wpt(route_temp, waypoint_temp);
@@ -1430,6 +1427,11 @@ void TpoFormatBase::tpo_process_compass()
 //
 void TpoFormatBase::tpo_read_3_x()
 {
+  // Global index to waypoints, needed for routes, filled in by
+  // tpo_process_waypoints.
+  //
+  // For version 3.x files.
+  QList<Waypoint> tpo_wp_index;
 
   if (doing_trks) {
 //printf("Processing Tracks\n");
@@ -1438,7 +1440,7 @@ void TpoFormatBase::tpo_read_3_x()
 
   if (doing_wpts || doing_rtes) {
 //printf("Processing Waypoints\n");
-    tpo_process_waypoints();
+    tpo_process_waypoints(tpo_wp_index);
   }
 
   if (doing_rtes) {
@@ -1448,7 +1450,7 @@ void TpoFormatBase::tpo_read_3_x()
     // for routes.
     //
 //printf("Processing Routes\n");
-    tpo_process_routes();
+    tpo_process_routes(tpo_wp_index);
   }
 
   if (doing_wpts) {
@@ -1487,12 +1489,6 @@ void TpoFormatBase::tpo_read_3_x()
 void
 TpoFormatBase::tpo_rd_init(const QString& fname)
 {
-
-  // prepare for an attempt to deallocate memory that may or may not get allocated
-  // depending on the options used.
-  tpo_index_ptr = 0;
-  tpo_wp_index = nullptr;
-
   tpo_file_in = gbfopen_le(fname, "rb", MYNAME);
   tpo_check_version_string();
 
@@ -1517,18 +1513,6 @@ TpoFormatBase::tpo_rd_init(const QString& fname)
 void
 TpoFormatBase::tpo_rd_deinit()
 {
-  // Free the waypoint index, we don't need it anymore.
-  for (unsigned int i = 0; i < tpo_index_ptr; i++) {
-    delete tpo_wp_index[i];
-  }
-  tpo_index_ptr = 0;
-
-  // Free the index array itself
-  if (tpo_wp_index) {
-    xfree(tpo_wp_index);
-    tpo_wp_index = nullptr;
-  }
-
   gbfclose(tpo_file_in);
 }
 
diff --git a/tpo.h b/tpo.h
index ddcf9ebc99ff77fc5bbc4e55168fc5d152667255..e390cb3977e9f112fcb6044830b4eac6100f1b15 100644 (file)
--- a/tpo.h
+++ b/tpo.h
@@ -71,6 +71,7 @@
 #ifndef TPO_H_INCLUDED_
 #define TPO_H_INCLUDED_
 
+#include <QList>     // for QList
 #include <QString>   // for QString
 #include <QVector>   // for QVector
 #include <cstdint>   // for uint8_t
@@ -107,11 +108,11 @@ protected:
   int tpo_find_block(unsigned int block_desired);
   static Waypoint* tpo_convert_ll(int lat, int lon);
   void tpo_process_tracks();
-  void tpo_process_waypoints();
+  void tpo_process_waypoints(QList<Waypoint>& tpo_wp_index);
   void tpo_process_map_notes();
   void tpo_process_symbols();
   void tpo_process_text_labels();
-  void tpo_process_routes();
+  void tpo_process_routes(const QList<Waypoint>& tpo_wp_index);
   void tpo_read_3_x();
   void tpo_rd_init(const QString& fname);
   void tpo_rd_deinit();
@@ -124,13 +125,6 @@ protected:
 
   // Define a global here that we can query from multiple places.
   float tpo_version = 0.0;
-
-  // Global index to waypoints, needed for routes, filled in by
-  // tpo_process_waypoints.
-  //
-  // For version 3.x files.
-  Waypoint** tpo_wp_index{};
-  unsigned int tpo_index_ptr{};
 };
 
 class Tpo2Format : public Format, private TpoFormatBase
diff --git a/util.cc b/util.cc
index d0dcbcd13869183362674f390e24a272b94c9d4e..7285c7467f0049e1cb45f0820de32c092e1b674e 100644 (file)
--- a/util.cc
+++ b/util.cc
@@ -20,7 +20,7 @@
  */
 
 #include <algorithm>                    // for sort
-#include <cctype>                       // for isspace, isalpha, ispunct, tolower, toupper
+#include <cctype>                       // for isspace, tolower
 #include <cerrno>                       // for errno
 #include <climits>                      // for INT_MAX, INT_MIN
 #include <cmath>                        // for fabs, floor
@@ -570,66 +570,60 @@ rot13(const QString& s)
  */
 
 QString
-convert_human_date_format(const char* human_datef)
+convert_human_date_format(const QString& human_datef)
 {
-  char* result = (char*) xcalloc((2*strlen(human_datef)) + 1, 1);
-  char* cout = result;
-  char prev = '\0';
+  QString result;
+  QChar prev = '\0';
   int ylen = 0;
 
-  for (const char* cin = human_datef; *cin; cin++) {
-    char okay = 1;
+  for (const QChar cin : human_datef) {
+    bool okay = true;
 
-    if (toupper(*cin) != 'Y') {
+    if (cin.toUpper() != 'Y') {
       ylen = 0;
     }
-    if (isalpha(*cin)) {
-      switch (*cin) {
+    if (cin.isLetter()) {
+      switch (cin.unicode()) {
       case 'y':
       case 'Y':
         if (prev != 'Y') {
-          strcat(cout, "%y");
-          cout += 2;
+          result.append("%y");
           prev = 'Y';
         }
         ylen++;
         if (ylen > 2) {
-          *(cout-1) = 'Y';
+          result.back() = 'Y';
         }
         break;
       case 'm':
       case 'M':
         if (prev != 'M') {
-          strcat(cout, "%m");
-          cout += 2;
+          result.append("%m");
           prev = 'M';
         }
         break;
       case 'd':
       case 'D':
         if (prev != 'D') {
-          strcat(cout, "%d");
-          cout += 2;
+          result.append("%d");
           prev = 'D';
         }
         break;
       default:
-        okay = 0;
+        okay = false;
       }
-    } else if (ispunct(*cin)) {
-      *cout++ = *cin;
+    } else if (cin.isPunct()) {
+      result.append(cin);
       prev = '\0';
     } else {
-      okay = 0;
+      okay = false;
     }
 
-    if (okay == 0) {
-      fatal("Invalid character \"%c\" in date format \"%s\"!\n", *cin, human_datef);
+    if (!okay) {
+      fatal(FatalMsg().nospace() << "Invalid character " << cin << " in date format " << human_datef << "!");
     }
   }
-  QString rv(result);
-  xfree(result);
-  return rv;
+  return result;
 }
 
 /*
@@ -638,22 +632,20 @@ convert_human_date_format(const char* human_datef)
  */
 
 QString
-convert_human_time_format(const char* human_timef)
+convert_human_time_format(const QString& human_timef)
 {
-  char* result = (char*) xcalloc((2*strlen(human_timef)) + 1, 1);
-  char* cout = result;
-  char prev = '\0';
+  QString result;
+  QChar prev = '\0';
 
-  for (const char* cin = human_timef; *cin; cin++) {
-    int okay = 1;
+  for (const QChar cin : human_timef) {
+    bool okay = true;
 
-    if (isalpha(*cin)) {
-      switch (*cin) {
+    if (cin.isLetter()) {
+      switch (cin.unicode()) {
       case 'S':
       case 's':
         if (prev != 'S') {
-          strcat(cout, "%S");
-          cout += 2;
+          result.append("%S");
           prev = 'S';
         }
         break;
@@ -661,69 +653,62 @@ convert_human_time_format(const char* human_timef)
       case 'M':
       case 'm':
         if (prev != 'M') {
-          strcat(cout, "%M");
-          cout += 2;
+          result.append("%M");
           prev = 'M';
         }
         break;
 
       case 'h':                                /* 12-hour-clock */
         if (prev != 'H') {
-          strcat(cout, "%l");  /* 1 .. 12 */
-          cout += 2;
+          result.append("%l"); /* 1 .. 12 */
           prev = 'H';
         } else {
-          *(cout-1) = 'I';  /* 01 .. 12 */
+          result.back() = 'I';  /* 01 .. 12 */
         }
         break;
 
       case 'H':                                /* 24-hour-clock */
         if (prev != 'H') {
-          strcat(cout, "%k");
-          cout += 2;
+          result.append("%k");
           prev = 'H';
         } else {
-          *(cout-1) = 'H';
+          result.back() = 'H';
         }
         break;
 
       case 'x':
         if (prev != 'X') {
-          strcat(cout, "%P");
-          cout += 2;
+          result.append("%P");
           prev = 'X';
         } else {
-          *(cout-1) = 'P';
+          result.back() = 'P';
         }
         break;
 
       case 'X':
         if (prev != 'X') {
-          strcat(cout, "%p");
-          cout += 2;
+          result.append("%p");
           prev = 'X';
         } else {
-          *(cout-1) = 'p';
+          result.back() = 'p';
         }
         break;
 
       default:
-        okay = 0;
+        okay = false;
       }
-    } else if (ispunct(*cin) || isspace(*cin)) {
-      *cout++ = *cin;
+    } else if (cin.isPunct() || cin.isSpace()) {
+      result.append(cin);
       prev = '\0';
     } else {
-      okay = 0;
+      okay = false;
     }
 
-    if (okay == 0) {
-      fatal("Invalid character \"%c\" in time format \"%s\"!\n", *cin, human_timef);
+    if (!okay) {
+      fatal(FatalMsg().nospace() << "Invalid character " << cin << " in time format " << human_timef << "!");
     }
   }
-  QString rv(result);
-  xfree(result);
-  return rv;
+  return result;
 }